#!/usr/bin/env node

/**
 * WGT热更新发布脚本 - 优化版
 * 自动处理WGT包的移动、重命名和版本管理
 */

const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')

class UpdatePublisher {
  constructor(options = {}) {
    this.projectRoot = process.cwd()
    this.moeWebDir = path.join(this.projectRoot, 'moe_web')
    this.outputDir = path.join(this.projectRoot, 'updates')
    this.wgtSourceDir = path.join(this.moeWebDir, 'unpackage', 'release')
    this.updateInfoFile = 'update-info.json'
    
    // 配置选项
    this.options = {
      verbose: options.verbose || false,
      autoClean: options.autoClean || false // 自动清理旧版本
    }
  }

  /**
   * 发布更新
   */
  async publishUpdate(version, message = '', forceUpdate = false) {
    try {
      console.log(`🚀 开始发布版本 ${version}...`)
      
      // 1. 检查版本号格式
      if (!this.isValidVersion(version)) {
        throw new Error('❌ 版本号格式不正确，请使用 x.y.z 格式')
      }
      
      // 2. 检查是否有未提交的更改
      if (this.hasUncommittedChanges()) {
        console.warn('⚠️  警告: 检测到未提交的更改，建议先提交代码')
      }
      
      // 3. 创建输出目录
      this.ensureOutputDir()
      
      // 4. 查找并移动WGT包
      const wgtPath = await this.findAndMoveWgtPackage(version)
      
      // 5. 生成版本信息文件
      const updateInfo = this.generateUpdateInfo(version, message, forceUpdate, wgtPath)
      
      // 6. 保存版本信息
      this.saveUpdateInfo(updateInfo)
      
      // 7. 自动清理旧版本（可选）
      if (this.options.autoClean) {
        this.cleanOldVersions(version)
      }
      
      // 8. 显示发布信息
      this.showPublishInfo(version, wgtPath, updateInfo)
      
      console.log(`✅ 版本 ${version} 发布完成！`)
      console.log('\n📤 请将以下文件上传到Gitee仓库:')
      console.log(`   - ${path.relative(this.projectRoot, wgtPath)}`)
      console.log(`   - ${path.relative(this.projectRoot, path.join(this.moeWebDir, this.updateInfoFile))}`)
      
    } catch (error) {
      console.error('❌ 发布失败:', error.message)
      process.exit(1)
    }
  }

  /**
   * 检查版本号格式
   */
  isValidVersion(version) {
    const versionRegex = /^\d+\.\d+\.\d+$/
    return versionRegex.test(version)
  }

  /**
   * 检查是否有未提交的更改
   */
  hasUncommittedChanges() {
    try {
      const status = execSync('git status --porcelain', { encoding: 'utf8' })
      return status.trim().length > 0
    } catch (error) {
      return false
    }
  }

  /**
   * 创建输出目录
   */
  ensureOutputDir() {
    if (!fs.existsSync(this.outputDir)) {
      fs.mkdirSync(this.outputDir, { recursive: true })
      console.log(`📁 创建输出目录: ${this.outputDir}`)
    }
  }

  /**
   * 查找并移动WGT包
   */
  async findAndMoveWgtPackage(version) {
    try {
      console.log('🔍 正在查找WGT包...')
      
      // 检查源目录是否存在
      if (!fs.existsSync(this.wgtSourceDir)) {
        throw new Error(`❌ WGT源目录不存在: ${this.wgtSourceDir}`)
      }
      
      // 查找WGT文件
      const wgtFiles = this.findWgtFiles(this.wgtSourceDir)
      
      if (wgtFiles.length === 0) {
        throw new Error('❌ 未找到WGT文件，请先编译生成WGT包')
      }
      
      console.log(`📦 找到 ${wgtFiles.length} 个WGT文件`)
      
      // 选择最新的WGT文件
      const latestWgtFile = this.selectLatestWgtFile(wgtFiles)
      console.log(`📋 选择最新的WGT文件: ${path.basename(latestWgtFile)}`)
      
      // 生成目标文件名
      const targetFileName = `update-v${version}.wgt`
      const targetPath = path.join(this.outputDir, targetFileName)
      
      // 检查目标文件是否已存在
      if (fs.existsSync(targetPath)) {
        console.log(`⚠️  目标文件已存在，将覆盖: ${targetFileName}`)
        fs.unlinkSync(targetPath)
      }
      
      // 移动文件
      console.log(`📦 正在移动WGT包...`)
      fs.copyFileSync(latestWgtFile, targetPath)
      
      // 验证文件大小
      const stats = fs.statSync(targetPath)
      console.log(`✅ WGT包移动成功，大小: ${this.formatFileSize(stats.size)}`)
      
      return targetPath
      
    } catch (error) {
      console.error('❌ 查找和移动WGT包失败:', error.message)
      throw error
    }
  }
  
  /**
   * 查找WGT文件
   */
  findWgtFiles(sourceDir) {
    const wgtFiles = []
    
    try {
      const files = fs.readdirSync(sourceDir)
      
      for (const file of files) {
        const filePath = path.join(sourceDir, file)
        const stat = fs.statSync(filePath)
        
        if (stat.isFile() && file.toLowerCase().endsWith('.wgt')) {
          wgtFiles.push(filePath)
        }
      }
    } catch (error) {
      console.error('❌ 读取源目录失败:', error.message)
    }
    
    return wgtFiles
  }
  
  /**
   * 选择最新的WGT文件
   */
  selectLatestWgtFile(wgtFiles) {
    if (wgtFiles.length === 1) {
      return wgtFiles[0]
    }
    
    // 按修改时间排序，选择最新的
    wgtFiles.sort((a, b) => {
      const statA = fs.statSync(a)
      const statB = fs.statSync(b)
      return statB.mtime - statA.mtime
    })
    
    return wgtFiles[0]
  }

  /**
   * 生成版本信息
   */
  generateUpdateInfo(version, message, forceUpdate, wgtPath) {
    const stat = fs.statSync(wgtPath)
    const commitSha = this.getGitCommitSha()
    const commitMessage = this.getGitCommitMessage()
    const commitDate = this.getGitCommitDate()
    
    // WGT包下载URL
    const downloadUrl = `https://gitee.com/xuxinzhi2206/moe_web/raw/master/updates/update-v${version}.wgt`
    
    return {
      version: version,
      downloadUrl: downloadUrl,
      size: stat.size,
      message: message || commitMessage,
      date: commitDate,
      forceUpdate: forceUpdate,
      commitSha: commitSha,
      generatedAt: new Date().toISOString()
    }
  }

  /**
   * 保存版本信息
   */
  saveUpdateInfo(updateInfo) {
    const infoPath = path.join(this.moeWebDir, this.updateInfoFile)
    fs.writeFileSync(infoPath, JSON.stringify(updateInfo, null, 2))
    console.log(`💾 版本信息已保存: ${path.relative(this.projectRoot, infoPath)}`)
  }

  /**
   * 自动清理旧版本
   */
  cleanOldVersions(currentVersion) {
    try {
      console.log('🧹 正在清理旧版本...')
      
      const files = fs.readdirSync(this.outputDir)
      const wgtFiles = files.filter(file => file.startsWith('update-v') && file.endsWith('.wgt'))
      
      let cleanedCount = 0
      for (const file of wgtFiles) {
        if (file !== `update-v${currentVersion}.wgt`) {
          const filePath = path.join(this.outputDir, file)
          fs.unlinkSync(filePath)
          console.log(`🗑️  已删除旧版本: ${file}`)
          cleanedCount++
        }
      }
      
      if (cleanedCount > 0) {
        console.log(`✅ 已清理 ${cleanedCount} 个旧版本文件`)
      } else {
        console.log('ℹ️  没有需要清理的旧版本文件')
      }
    } catch (error) {
      console.warn('⚠️  清理旧版本失败:', error.message)
    }
  }

  /**
   * 显示发布信息
   */
  showPublishInfo(version, wgtPath, updateInfo) {
    console.log('\n📋 === 发布信息 ===')
    console.log(`📦 版本: ${version}`)
    console.log(`💬 消息: ${updateInfo.message}`)
    console.log(`📏 大小: ${this.formatFileSize(updateInfo.size)}`)
    console.log(`🔒 强制更新: ${updateInfo.forceUpdate ? '是' : '否'}`)
    console.log(`🔑 提交SHA: ${updateInfo.commitSha}`)
    console.log(`⏰ 生成时间: ${updateInfo.generatedAt}`)
    console.log('==================\n')
  }

  /**
   * 获取Git提交SHA
   */
  getGitCommitSha() {
    try {
      return execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim()
    } catch (error) {
      return ''
    }
  }

  /**
   * 获取Git提交信息
   */
  getGitCommitMessage() {
    try {
      return execSync('git log -1 --pretty=%B', { encoding: 'utf8' }).trim()
    } catch (error) {
      return ''
    }
  }

  /**
   * 获取Git提交日期
   */
  getGitCommitDate() {
    try {
      return execSync('git log -1 --pretty=%cI', { encoding: 'utf8' }).trim()
    } catch (error) {
      return new Date().toISOString()
    }
  }

  /**
   * 格式化文件大小
   */
  formatFileSize(bytes) {
    if (bytes === 0) return '0 B'
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }
}

// 命令行参数处理
if (require.main === module) {
  const args = process.argv.slice(2)
  
  if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
    console.log('🚀 WGT热更新发布脚本 - 优化版')
    console.log('')
    console.log('用法: node publish-update.js <版本号> [消息] [选项]')
    console.log('')
    console.log('参数:')
    console.log('  <版本号>    版本号，格式: x.y.z (例如: 1.3.2)')
    console.log('  [消息]      更新说明 (可选)')
    console.log('')
    console.log('选项:')
    console.log('  --force                   强制更新')
    console.log('  --verbose                 详细输出')
    console.log('  --auto-clean              自动清理旧版本')
    console.log('  --help, -h                显示帮助信息')
    console.log('')
    console.log('功能:')
    console.log('  ✅ 自动查找 moe_web/unpackage/release/ 目录下的WGT文件')
    console.log('  ✅ 自动移动到 updates/ 目录并重命名')
    console.log('  ✅ 自动生成版本信息文件')
    console.log('  ✅ 支持自动清理旧版本')
    console.log('  ✅ 提供详细的执行日志')
    console.log('')
    console.log('示例:')
    console.log('  node publish-update.js 1.3.2 "修复登录问题"')
    console.log('  node publish-update.js 1.3.3 "重要更新" --force')
    console.log('  node publish-update.js 1.3.4 "功能更新" --verbose --auto-clean')
    process.exit(0)
  }
  
  // 解析参数
  const version = args[0]
  let message = ''
  let forceUpdate = false
  let verbose = false
  let autoClean = false
  
  // 解析选项
  for (let i = 1; i < args.length; i++) {
    const arg = args[i]
    
    if (arg === '--force') {
      forceUpdate = true
    } else if (arg === '--verbose') {
      verbose = true
    } else if (arg === '--auto-clean') {
      autoClean = true
    } else if (!arg.startsWith('--')) {
      // 非选项参数作为消息
      if (!message) {
        message = arg
      }
    }
  }
  
  const options = {
    verbose,
    autoClean
  }
  
  const publisher = new UpdatePublisher(options)
  publisher.publishUpdate(version, message, forceUpdate)
}

module.exports = UpdatePublisher
